/* canvas 画板 */

var canvas_drawingBoard = (function () {

    var __class = function () { this.__self = this; };
    __class.prototype.getSelf = function (str) {
        return this.__self;
    }

    //判断是否是移动设备
    __class.prototype.isMobile = function(){
        if( navigator.userAgent.match(/Android/i)
            || navigator.userAgent.match(/webOS/i)
            || navigator.userAgent.match(/iPhone/i)
            || navigator.userAgent.match(/iPad/i)
            || navigator.userAgent.match(/iPod/i)
            || navigator.userAgent.match(/BlackBerry/i)
            || navigator.userAgent.match(/Windows Phone/i)
        )return true;
        return false;
    }

    /*
        @decoration 初始化方法，必须执行
        @param  dom  Object  canvas的dom对象
        @param  context  Object  canvas的上下文对象
        @param  colorDomId  Object  颜色拾取器dom的id名
    */
    __class.prototype.init = function (canvasDom, context, colorDomId) {
        this.__self.canvasDom = canvasDom;
        this.__self.context = context;
        this.__self.colorDomId = colorDomId;

        var that = this;

        //获取canvas宽高
        this.__self.canvasW = this.__self.canvasDom.width();
        this.__self.canvasH = this.__self.canvasDom.height();

        //用于判断用户是否按下了鼠标，初始为false状态
        this.__self.isMouseDown = false;
        //用于存储线条绘制速度的时间
        this.__self.lastTimestamp = 0;
        //用于记录上一次鼠标的位置
        this.__self.lastLoc = { x: 0, y: 0 };
        //用于使绘制的线条更加平滑，计算用
        this.__self.lastLineWidth = -1;

        //定义画笔属性
        this.__self.maxLineWidth = 30; //最大笔画粗细
        this.__self.minLineWidth = 1; //最小笔画粗细
        this.__self.maxStrokeV = 10; //最大笔画书写速度
        this.__self.minStrokeV = 0.1; //最小笔画书写速度
        this.__self.lineWidth = 1;  //画笔实际大小
        //用于存储当前画笔的颜色
        this.__self.strokeColor = 'black';

        //扩展canvas，画虚线
        this.__self.setDashed();

        //防止重复绘制米字虚线
        this.__self.riceFlag = false;

        //初始化颜色拾取器
        this.__self.initColorSelect();

        /*触屏上的事件*/
        if(this.__self.isMobile()){

            console.log("是移动设备");

            //触控开始
            this.__self.canvasDom.on('touchstart', function (e) {
                that.__self.preventDefault(e);
                //如果是多点触控，那么只响应第一个触控点
                var touch = e.originalEvent.targetTouches[0];
                console.log(touch)
                //绘制中要处理的
                that.__self.beginStroke({ x: touch.pageX, y: touch.pageY }); //这里传入触控点对应的canvas坐标
            });
            //触控中
            this.__self.canvasDom.on('touchmove', function (e) {
                that.__self.preventDefault(e);
                //如果鼠标按下，则开始绘制线条
                if (that.__self.isMouseDown) {
                    //如果是多点触控，那么只响应第一个触控点
                    var touch = e.originalEvent.targetTouches[0];
                    //绘制中要处理的
                    that.__self.moveStoke({ x: touch.pageX, y: touch.pageY }); //这里传入触控点对应的canvas坐标
                }
            });
            //触控结束
            this.__self.canvasDom.on('touchend', function (e) {
                that.__self.preventDefault(e);

                //鼠标没有按下/弹起了
                that.__self.endStroke();
            });

        }else{  /* PC上的事件 */

            console.log("是PC设备");

            //鼠标按下事件
            this.__self.canvasDom.on('mousedown', function (e) {
                that.__self.preventDefault(e);
                that.__self.beginStroke({ x: e.clientX, y: e.clientY });
            });
            //鼠标弹起事件
            this.__self.canvasDom.on('mouseup', function (e) {
                that.__self.preventDefault(e);
                //鼠标没有按下/弹起了
                that.__self.endStroke();
            });
    
            //鼠标移出事件
            this.__self.canvasDom.on('mouseout', function (e) {
                that.__self.preventDefault(e);
                //鼠标没有按下/弹起了
                that.__self.endStroke();
            });
    
            //鼠标移动事件
            this.__self.canvasDom.on('mousemove', function (e) {
                that.__self.preventDefault(e);
                //如果鼠标按下，则开始绘制线条
                if (that.__self.isMouseDown) {
                    //绘制中要处理的
                    that.__self.moveStoke({ x: e.clientX, y: e.clientY });
                }
            });

        }

    }

    /* 
        @decoration 初始化颜色拾取器
    */
    __class.prototype.initColorSelect = function(){
        var that = this;
        var a = Colorpicker.create({
            el: this.__self.colorDomId,
            color: "#ff0000",
            change: function (elem, hex) {
                elem.style.backgroundColor = hex;
                //改变画笔颜色
                that.__self.strokeColor = hex;
            }
        })
    }

    /* 
        @decoration 扩展canvas，画虚线
    */
    __class.prototype.setDashed = function () {
        var context = this.__self.context;
        var moveToFunction = CanvasRenderingContext2D.prototype.moveTo;
        CanvasRenderingContext2D.prototype.lastMoveToLocation = {};

        CanvasRenderingContext2D.prototype.moveTo = function (x, y) {
            moveToFunction.apply(context, [x, y]);
            this.lastMoveToLocation.x = x;
            this.lastMoveToLocation.y = y;
        }

        CanvasRenderingContext2D.prototype.dashedLineTo = function (x, y, dashLength) {
            dashLength = dashLength === undefined ? 5 : dashLength;
            var startX = this.lastMoveToLocation.x;
            var startY = this.lastMoveToLocation.y;
            var deltaX = x - startX;
            var deltaY = y - startY;
            var numDashes = Math.floor(Math.sqrt(deltaX * deltaX + deltaY * deltaY) / dashLength);
            for (var i = 0; i < numDashes; i++) {
                this[i % 2 === 0 ? 'moveTo' : 'lineTo'](startX + (deltaX / numDashes) * i,
                    startY + (deltaY / numDashes) * i);
            }
            this.moveTo(x, y);
        }
    }

    /* 
        @decoration 绘制米字虚线
    */
    __class.prototype.setRice = function () {

        if(this.__self.riceFlag){return}

        //绘制红色边框
        this.__self.context.strokeStyle = 'rgb(230,11,9)';
        this.__self.context.beginPath();
        this.__self.context.moveTo(3, 3);
        this.__self.context.lineTo(this.__self.canvasW - 3, 3);
        this.__self.context.lineTo(this.__self.canvasW - 3, this.__self.canvasH - 3);
        this.__self.context.lineTo(3, this.__self.canvasH - 3);
        this.__self.context.closePath();
        this.__self.context.lineWidth = 6;
        this.__self.context.stroke();

        //绘制米字的各线段
        this.__self.context.beginPath();
        this.__self.context.moveTo(0, 0);
        this.__self.context.lineTo(this.__self.canvasW, this.__self.canvasH);
        this.__self.context.moveTo(this.__self.canvasW, 0);
        this.__self.context.lineTo(0, this.__self.canvasH);
        this.__self.context.moveTo(this.__self.canvasW / 2, 0);
        this.__self.context.dashedLineTo(this.__self.canvasW / 2, this.__self.canvasH, 3);
        this.__self.context.moveTo(0, this.__self.canvasH / 2);
        this.__self.context.dashedLineTo(this.__self.canvasW, this.__self.canvasH / 2, 3);
        this.__self.context.lineWidth = 1;
        this.__self.context.stroke();

        this.__self.riceFlag = true;
    }

    //阻止事件的默认行为，比如a的href默认行为
    __class.prototype.preventDefault = function (event) {
        event = event ? event : window.event;
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    }

    //获取鼠标在canvas元素上的坐标位置
    __class.prototype.windowToCanvas = function (x, y) {
        var bbox = document.getElementById('canvas1').getBoundingClientRect(); //获取canvas元素的边界框
        //返回鼠标在canvas元素上的坐标位置

        
        var obj = {
            x: x - bbox.left * (this.__self.canvasDom.width() / bbox.width),
            y: y - bbox.top * (this.__self.canvasDom.height() / bbox.height)
        }
        return obj;
    }

    //获取线段两点之间的距离，用于对线条粗细进行控制
    __class.prototype.calcDistance = function (loc1, loc2) {
        return Math.sqrt((loc1.x - loc2.x) * (loc1.x - loc2.x) + (loc1.y - loc2.y) * (loc1.y - loc2.y));
    }

    //计算速度（运笔速度）
    __class.prototype.calcLineWidt = function (t, s) {
        var v = s / t;
        var resultLineWidth;

        //设置线条不能小于0像素，不能大于30像素
        if (v <= this.__self.minStrokeV) {
            resultLineWidth = this.__self.maxLineWidth;
        } else if (v >= this.__self.maxStrokeV) {
            resultLineWidth = this.__self.minLineWidth;
        } else {
            resultLineWidth = this.__self.maxLineWidth - (v - this.__self.minStrokeV) / (this.__self.maxStrokeV - this.__self.minStrokeV) * (this.__self.maxLineWidth - this.__self.minLineWidth);
        }

        //更加平滑
        if (this.__self.lastLineWidth == -1) {
            return resultLineWidth;
        }
        return this.__self.lastLineWidth * 2 / 3 + resultLineWidth * 1 / 3;
    }

    //绘制开始要处理的
    __class.prototype.beginStroke = function (point) {
        //鼠标按下
        this.__self.isMouseDown = true;
        //获取鼠标在canvas上的位置
        this.__self.lastLoc = this.__self.windowToCanvas(point.x, point.y);
        //获取当前时间的毫秒数（上一次鼠标按下的时间）
        this.__self.lastTimestamp = new Date().getTime();
    }

    //绘制结束要处理的
    __class.prototype.endStroke = function () {
        //鼠标没有按下/弹起了
        this.__self.isMouseDown = false;
    }

    //绘制中要处理的
    __class.prototype.moveStoke = function (point) {
        //获取鼠标在canvas上的位置
        var loc = this.__self.windowToCanvas(point.x, point.y);
        //获取线段两点之间的距离
        var s = this.__self.calcDistance(loc, this.__self.lastLoc);
        //获取当前时间的毫秒数（当前鼠标按下的时间）
        var curTimestamp = new Date().getTime();
        //计算鼠标按下并移动了多长时间
        var t = curTimestamp - this.__self.lastTimestamp;
        //计算速度
        var lineWidth = this.__self.calcLineWidt(t, s);

        //绘制线段，字的书写效果
        this.__self.context.beginPath();
        this.__self.context.moveTo(this.__self.lastLoc.x, this.__self.lastLoc.y);
        this.__self.context.lineTo(loc.x, loc.y);
        this.__self.context.strokeStyle = this.__self.strokeColor;
        this.__self.context.lineWidth = this.__self.lineWidth;
        this.__self.context.lineCap = 'round'; //设置线段的样式为圆角平滑过渡
        this.__self.context.lineJoin = 'round'; //使线段更加平滑
        this.__self.context.stroke();

        //更新上一次鼠标位置为本次鼠标位置
        this.__self.lastLoc = loc;
        //更新鼠标按下并移动了多长时间
        this.__self.lastTimestamp = curTimestamp;
        //更新线条宽度
        this.__self.lastLineWidth = lineWidth;
    }

    return new __class();
})();